package com.apes.scm.rbac.model;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.DefaultPersistListener;
import com.apes.framework.jpa.Model;
import com.apes.framework.jpa.comment.Comment;
import com.apes.framework.jpa.generator.ApesGenerator;
import com.apes.hr.base.model.WorkPost;
import com.apes.hr.base.repository.WorkPostRepository;
import com.apes.scm.masterdata.enumeration.model.Enumeration;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.party.model.Person;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;
import com.apestech.framework.util.StringUtil;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.SelectBeforeUpdate;
import org.springframework.util.StringUtils;

import javax.persistence.*;
import java.util.*;

/**
 * 功能：系统菜单
 *
 * @author xul
 * @create 2018-03-15 16:00
 */
@Getter
@Setter
@SelectBeforeUpdate
@DynamicInsert
@DynamicUpdate
@Entity
@EntityListeners(DefaultPersistListener.class)
@Table(name = Menu.CONST_TABLE_NAME, indexes = {@Index(name = "i_aut_menus_parent_id", columnList = "parent_id")})
public class Menu extends Model {
    public static final String CONST_TABLE_NAME = "aut_menus";

    @Id
    @Column(name = "id")
    @ApesGenerator(code = CONST_TABLE_NAME, name = "菜单")
    private Integer id;

    @Column(name = "name", length = 60)
    private String name; //名称

    @Column(name = "sort_code", length = 8, nullable = false)
    private String sortCode; //排序码

    @Column(name = "icon", length = 30)
    private String icon; //图标

    @Column(name = "link", length = 256)
    private String link; //链接

    @Column(name = "flow_id", length = 30)
    private String flowId; //流程
//
//    @Column(name = "terminal", length = 30)
//    private String terminal; //终端

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "terminal_type", referencedColumnName = "id")
    @Comment("终端")
    private Enumeration terminalType;

    @Column(name = "valid", nullable = false)
    private boolean valid = true; //有效

//    @Column(name = "is_last")
//    private boolean isLast; //末级

    @Column(name = "translate", length = 60)
    private String translate; //国际化Key值
//
//    @Column(name = "grouping", length = 32)
//    private String grouping; //分组

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "group_type", referencedColumnName = "id")
    @Comment("分组")
    private Enumeration groupType;

    @Column(name = "group_sign", nullable = false)
    private boolean group = false; //分组标识

    @Column(name = "combination_menu", nullable = false, columnDefinition = "number(1,0) default 0")
    private boolean combinationMenu = false; //组合菜单

    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_id")
    private Menu parent;

    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Set<Menu> children;

    @OneToMany(mappedBy = "menu", cascade = CascadeType.ALL, orphanRemoval = true)
    @OrderBy("name asc")
    private Set<Operation> operations = new HashSet<>();

    @Column(name = "initials", length = 256)
    @Comment("拼音首字母")
    private String initials;

    @Column(name="develop_users", length = 4000)
    @Comment("研发人员")
    private String developUsers;

    @Transient
    private Set<PartyRole> developUserList;  // 研发人员

    public void setDevelopUsers(String developUsers) {
        this.developUsers = developUsers;
    }

    public Set<Operation> getOperations() {
        if (operations == null || operations.isEmpty()) return null;
        for (Operation item : operations) {
            item.setMenu(this);
        }
        return operations;
    }

    /*树层级结构*/
    @Column(name = "path", length = 4000)
    private String path;

    public String localPath() {
        String path = null;
        if (parent != null) path = parent.localPath();
        return path != null ? path + "/" + id : id + "";
    }

    /**
     * 临时字段：权限菜单
     **/
    @Transient
    Map<Integer, Menu> menus = new HashMap<>();

    /**
     * 临时字段：权限操作
     **/
    @Transient
    Map<String, Operation> authOperations = new HashMap<>();

    /**
     * 按钮权限列表
     */
    @Transient
    private String operationNames;

    @Transient
    public String getOperationNames () {
        String names = "";
        for (Operation operation : operations) {
            names += operation.getName() + ";";
        }
        return names;
    }

    @Transient
    private List<MenuAuthItem> menuAuthItemList = new ArrayList<>();

    public Set<PartyRole> getDevelopUserList() {
        if (isWrite() || isLoad()) {
            this.developUserList = getDevelopUser(developUsers);
        }
        return developUserList;
    }
    public void setDevelopUserList(Set<PartyRole> developUserList) {
        this.developUserList = developUserList;
        if (!isWrite()) {
            this.setDevelopUsers(toDevelopUser(developUserList));
        }
    }


    @Transient
    public Set<PartyRole> getDevelopUser(String source) {
        if (StringUtil.isEmpty(source)) return null;
        Set<PartyRole> persons = new HashSet<>();
        String[] rows = source.split(";");
        for (String person : rows) {
            if (person.contains("|")) {
                persons.add(SpringManager.getBean(PartyRoleRepository.class).findOne(StringUtils.split(person, "|")[0]));
            }
        }
        return persons;
    }

    public String toDevelopUser(Set<PartyRole> partyRoles) {
        StringBuffer sb = new StringBuffer();
        for (PartyRole partyRole : partyRoles) {
            if (sb.length() > 0) {
                sb.append(";");
            }
            sb.append(partyRole.getId());
            sb.append("|");
            sb.append(partyRole.getName());  // 格式 id|description;
        }
        return sb.toString();
    }
}
